from panda3d.core import Vec3, VBase3
import database.units


class WebUnit(object):

    def __init__(self, name, speed, radius, hp, worth, upgrades, cost, weapon):
        self.speed = speed
        self.name = name
        self.upgrades = upgrades
        self.cost = cost
        self.amount = 1
        self.radius = radius
        self.faced = False
        self.pos = Vec3(0, 0, 0)
        self.destination = Vec3(0, 0, 0)
        self.manager = None
        self.hp = hp
        self.worth = worth
        self.dead = False
        self.weapon = database.units.get_weapon(weapon)
        self.target = None

    def move(self, tpf):
        direct = -self.pos + self.destination
        VBase3.normalize(direct)
        direct *= (self.speed*tpf*0.5)
        self.set_relative_position(direct)
        if self.faced:
            self.faced = False
            self.manager.player.session.broadcast_unitdestination(self, (0, 0))

    def set_relative_position(self, dir):
        self.pos += dir

    def set_destination(self, x, y):
        self.destination = Vec3(x, y, 0)

    def set_destinationV(self, des):
        self.destination = des

    def damage(self, dmg):
        if self.dead:
            return
        self.hp -= dmg
        if self.hp <= 0:
            self.dead = True
            self.manager.destiny(self, 0)

    def destination_reached(self):
        approx = -self.pos + self.destination
        approx = VBase3.length(approx)
        if approx < 2.5:
            return True
        return False

    def update(self, tpf, towers):
        if not self.destination_reached():
            if self.target is None or self.target.dead:
                self.move(tpf)
                self.scan_for_target(towers)
            else:
                self.attack_directive(tpf)
        else:
            self.dead = True
            self.manager.destiny(self, 1)

    def attack_directive(self, dt):
        if not self.in_range():
            self.move_to_target(dt)
        else:
            self.attack(dt)

    def move_to_target(self, dt):
        direct = -self.pos + self.target.pos
        VBase3.normalize(direct)
        direct *= (self.speed*dt*0.5)
        self.set_relative_position(direct)

    def attack(self, dt):
        self.weapon.cooldown -= dt
        if self.weapon.cooldown <= 0:
            self.weapon.cooldown += self.weapon.atkrate
            if self.weapon.direct:
                self.target.damage(self.weapon.damage)
            else:
                self.manager.player.session.towermanager.fire_projectile(self.weapon.animation, self.target, self.pos, 0)

    def in_range(self):
        dis = self.target.pos - self.pos
        quadrad = (self.radius*self.radius)+(self.target.radius*self.target.radius)+(self.weapon.range*self.weapon.range)
        print quadrad
        quaddis = dis.x*dis.x+dis.y*dis.y
        print quaddis
        if quaddis <= quadrad:
            return True
        return False

    def scan_for_target(self, towers):
        for t in towers:
            dis = t.pos - self.pos
            quadrad = t.aggro * t.aggro
            quaddis = dis.x*dis.x+dis.y*dis.y
            if quaddis < quadrad:
                self.target = t
                self.manager.player.session.broadcast_unitdestination(self, t.pos)
                self.faced = True

    def remove_node(self):
        self.model.remove_node()
        self.unit_object.remove_node()
        self.unit_object = None

    def towercollisions(self, towers):
        for t in towers:
            leng = t.pos - self.pos
            #len = len.x*len.x + len.y * len.y
            #dis = (t.radius + self.radius)*(t.radius + self.radius)
            leng = VBase3.length(leng)
            dis = t.radius + self.radius
            if leng < dis:
                self.set_relative_position((self.pos - t.pos) * (dis - leng))
